﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace Strategia.Simulation
{
    public class Maths
    {
        public float lambda = 0.4f;//0.26f;0.4f;//0.025f; //przewodnosc cieplna  
        public float R = 0.181f; //opornosc powierzchni (sciany)
        public float odleglosc = 1.0f; //odleglosc pomiedzy srodkami 
        public float krok = 1.0f; //rozsadny krok to krok < C * x * y * z / Stala_suma_K
        public float C = 0.001211f; //pojemnosc cieplna powietrza

        public float xmin;
        public float xmax;
        public float ymin;
        public float ymax;
        public float zmin;
        public float zmax;

        public float K_srodek;
        public float K_zew;
        public float podzialka;
        public float K_suma;

        public Maths(float _xmin, float _xmax, float _ymin, float _ymax, float _zmin, float _zmax)
        {
            this.xmin = _xmin;
            this.xmax = _xmax;
            this.ymin = _ymin;
            this.ymax = _ymax;
            this.zmin = _zmin;
            this.zmax = _zmax;

            podzialka = (float)Program.podzialkaX / 100f;

            K_srodek = (podzialka * podzialka) / (podzialka / 2 * lambda + podzialka / 2 * lambda);
            K_zew = (podzialka * podzialka) / (podzialka / (2 * lambda) + R);
            K_suma = 6 * K_srodek;
            C = (krok * K_suma) / (podzialka*podzialka*podzialka);
        }

        public float H_srodek(float x, float y, float z, List<List<List<float>>> lista)
        {
            float wy = K_srodek * (T_cella(x - odleglosc, y, z, lista) - T_cella(x, y, z, lista)) + //lewo
                   K_srodek * (T_cella(x + odleglosc, y, z, lista) - T_cella(x, y, z, lista)) + //prawo
                   K_srodek * (T_cella(x, y - odleglosc, z, lista) - T_cella(x, y, z, lista)) + //przod
                   K_srodek * (T_cella(x, y + odleglosc, z, lista) - T_cella(x, y, z, lista)) + //tyl
                   K_srodek * (T_cella(x, y, z - odleglosc, lista) - T_cella(x, y, z, lista)) + //dol
                   K_srodek * (T_cella(x, y, z + odleglosc, lista) - T_cella(x, y, z, lista)); //gora

            return wy;
        }

        public float H_zew(float x, float y, float z, List<List<List<float>>> lista)
        {
            float wynik = 0;

            //dol, pod uwage bierzemy cella za 
            if (y == ymin)
            {
                wynik += K_zew * (T_cella(x, y + odleglosc, z, lista) - T_cella(x, y, z, lista));
            }
            //dol, pod uwage bierzemy cella przed 
            else if (y == ymax)
            {
                wynik += K_zew * (T_cella(x, y - odleglosc, z, lista) - T_cella(x, y, z, lista));
            }
            //dol gora
            else
            {
                wynik += K_zew * (T_cella(x, y - odleglosc, z, lista) - T_cella(x, y, z, lista)) +
                         K_zew * (T_cella(x, y + odleglosc, z, lista) - T_cella(x, y, z, lista));
            }
            //lewa krawedz, bierzemy pod uwage cella z prawej
            if (x == xmin)
            {
                wynik += K_zew * (T_cella(x + odleglosc, y, z, lista) - T_cella(x, y, z, lista));
            }
            //prawa krawedz, bierzemy pod uwage cella z lewej
            else if (x == xmax)
            {
                wynik += K_zew * (T_cella(x - odleglosc, y, z, lista) - T_cella(x, y, z, lista));
            }
            //lewo prawo
            else
            {
                wynik += K_zew * (T_cella(x - odleglosc, y, z, lista) - T_cella(x, y, z, lista)) +
                   K_zew * (T_cella(x + odleglosc, y, z, lista) - T_cella(x, y, z, lista));
            }
            //dolna, bierzemy pod uwage cella na gorze
            if (z == zmin)
            {
                wynik += K_zew * (T_cella(x, y, z + odleglosc, lista) - T_cella(x, y, z, lista));
            }
            //gorna, bierzemy pod uwage cella na dole
            else if (z == zmax)
            {
                wynik += K_zew * (T_cella(x, y, z - odleglosc, lista) - T_cella(x, y, z, lista));
            }
            else
            {
                wynik += K_zew * (T_cella(x, y, z - odleglosc, lista) - T_cella(x, y, z, lista)) +
                   K_zew * (T_cella(x, y, z + odleglosc, lista) - T_cella(x, y, z, lista));
            }

            return wynik;
        }

        //Temperatura konkretnego cella
        public float T_cella(float x, float y, float z, List<List<List<float>>> lista)
        {
            float t = lista[(int)x - 1][(int)y - 1][(int)z - 1];
            return lista[(int)x - 1][(int)y - 1][(int)z - 1];
        }

        //szukana temperatura nowa konkretnego cella
        public float T_cella_nowa(float x, float y, float z, List<List<List<float>>> lista)
        {
            float t;
            if (x == xmin || x == xmax || y == ymin || y == ymax || z == zmin || z == zmax)
                t = T_cella(x, y, z, lista) + (krok * H_zew(x, y, z, lista)) / (C * podzialka * podzialka * podzialka);
            else
                t = T_cella(x, y, z, lista) + (krok * H_srodek(x, y, z, lista)) / (C * podzialka * podzialka * podzialka);

            return t;
        }  
    }
}